﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Actor : MonoBehaviour
{
    int sceneLayer = 0;
    readonly Vector2 g = new Vector2(0.0f, -5.0f);
    Vector2 RectSize = new Vector2(0.7f, 1.4f);
    public const float MinFloat = 0.01f;

    public float MaxXSpeed = 4.0f;
    public float XSpeedA = 5.0f;
    public float FrictionA = 5.0f;

    public float MaxXSpeedInSky = 4.0f;
    public float MaxControllerSpeedInSky = 2.0f;
    public float XSpeedAInSky = 3.0f;

    public GameObject GouHuo;

    public GameObject cooldamage;
    public GameObject yiyanghuatanDamage;
    public GameObject noO2damage;

    //  public Rigidbody2D rigibody;
    bool _insky;

    Vector2 currentSpeed;

    void Start()
    {
        sceneLayer = 1 << LayerMask.NameToLayer("Scene");
        StartCoroutine(DelayUpdate());
       
//        LeftController lc = GameObject.Find("UILeft").GetComponentInChildren<LeftController>();
        LeftController.instance.Move += this.Move;

//        Controller controller = GameObject.FindObjectOfType<Controller>();
        Controller.instance.JumpEvent += this.Jump;
//        Controller.instance.PutItemEvent += this.;

    }

    void Move(Vector2 dir)
    {
        Movedirection(dir.x);
    }

    float _movedirection;

    public void Movedirection(float value)
    {
        if (Mathf.Abs(value) < 0.2f)
        {
            _movedirection = 0.0f;
        }
        else
        {
            _movedirection = value;
        }
    }

    int jumpCount = 0;

    public void Jump()
    {
        jumpCount++;
        if(jumpCount > 3)
        {
            return;
        }
        Vector2 t = currentSpeed;
        t.y = 5.0f;
        currentSpeed = t;
    }

    public void Action()
    {
        MakeGouHuo();
    }

    void UpdateController()
    {
        if (_insky)
        {
            if (_movedirection > 0.0f)
            {
                Vector2 t = currentSpeed;
                if (t.x < MaxControllerSpeedInSky)
                {
                    t.x += Time.deltaTime * XSpeedAInSky;
                    t.x = Mathf.Min(t.x, MaxControllerSpeedInSky);
                }
                currentSpeed = t;
            }
            if (_movedirection < 0.0f)
            {
                Vector2 t = currentSpeed;
                if (t.x > -MaxControllerSpeedInSky)
                {
                    t.x -= Time.deltaTime * XSpeedAInSky;
                    t.x = Mathf.Max(t.x, -MaxControllerSpeedInSky);
                }
                currentSpeed = t;
            }
        }
        else
        {
            bool xcontroller = false;
            if (_movedirection > 0.0f)//KeyDown(KeyCode.D))
            {
                Vector2 t = currentSpeed;
                if(t.x < 0)
                {
                    t.x += Time.deltaTime * FrictionA;
                    t.x = Mathf.Min(t.x, MaxXSpeed);

                }
                else if (t.x < XSpeedA)
                {
                    t.x += Time.deltaTime * XSpeedA;
                    t.x = Mathf.Min(t.x, MaxXSpeed);
                }
                currentSpeed = t;
                xcontroller = true;
            }
            if (_movedirection < 0.0f)
            {
                Vector2 t = currentSpeed;
                if(t.x > 0)
                {
                    t.x -= Time.deltaTime * FrictionA;
                    t.x = Mathf.Max(t.x, -MaxXSpeed);
                }
                else if (t.x > -XSpeedA)
                {
                    t.x -= Time.deltaTime * XSpeedA;
                    t.x = Mathf.Max(t.x, -MaxXSpeed);
                }
                currentSpeed = t;
                xcontroller = true;
            }
            if (!xcontroller)   //如果在地面上没有任何水平方向的操作的话 则衰减速度
            {
                if(currentSpeed.x < 0 )
                {
                    currentSpeed.x += Time.deltaTime * FrictionA;
                    if(currentSpeed.x > 0)
                    {
                        currentSpeed.x = 0.0f;
                    }
                }
                if(currentSpeed.x > 0)
                {
                    currentSpeed.x -= Time.deltaTime * FrictionA;
                    if (currentSpeed.x < 0)
                    {
                        currentSpeed.x = 0.0f;
                    }

                }
            }
            if (Input.GetKeyDown(KeyCode.Z))
            {
            }
        }
    }


    void UpdateSpeed()
    {
        if (_insky)
        {
            currentSpeed += g * Time.deltaTime;
        }
        currentSpeed.y = Mathf.Max(-10.0f, currentSpeed.y);
    }

    void UpdateMove()
    {
        Vector2 normalSpeed = currentSpeed.normalized;
        float totallength = currentSpeed.magnitude * Time.deltaTime;

        RaycastHit2D hitresult = Physics2D.BoxCast(transform.position, RectSize, 0, normalSpeed, totallength,sceneLayer);
        if(hitresult.collider == null )  //如果没有碰到任何物体的话 则移动
        {
            //少移动那么一点点 防止 浮点数 误差
            Vector3 deletmove = new Vector3(currentSpeed.x * Time.deltaTime * 0.9f, currentSpeed.y * Time.deltaTime * 0.9f);
            transform.position = transform.position + deletmove;
        }
        else
        {
            //少移动那么一点点 防止 浮点数 误差
            //检查 撞到是 上下 还是左右
            if(hitresult.normal.y > 0 )
            {
                Vector3 deletmove = currentSpeed.normalized * hitresult.distance * 0.9f ;
                transform.position= transform.position + deletmove;
                //同时修正Y 
                Vector3 toedit = transform.position;
                float newy = hitresult.point.y + RectSize.y / 2 + MinFloat;
                toedit.y = newy;
                transform.position = toedit;                
                currentSpeed.y = 0.0f;
                _insky = false;
                Debug.Log("HitFloor");
            }
            if (hitresult.normal.y < 0)
            {
                Vector3 deletmove = currentSpeed.normalized * hitresult.distance * 0.9f;
                transform.position = transform.position + deletmove;
                //同时修正Y 
                Vector3 toedit = transform.position;
                float newy = hitresult.point.y -( RectSize.y / 2 + MinFloat);
                toedit.y = newy;
                transform.position = toedit;
                currentSpeed.y = 0.0f;
                currentSpeed.y = currentSpeed.y / 2.0f ;
                Debug.Log("撞到了天花板");
            }
            if(hitresult.normal.x < 0)
            {
                Vector3 deletmove = currentSpeed.normalized * hitresult.distance * 0.9f;
                transform.position = transform.position + deletmove;
                //同时修正X 
                Vector3 toedit = transform.position;
                float newx = hitresult.point.x -( RectSize.x / 2 + MinFloat);
                toedit.x = newx;
                
                transform.position = toedit;

                currentSpeed.x = 0.0f;
                Debug.Log("右边是墙");
            }
            if (hitresult.normal.x > 0)
            {
                Vector3 deletmove = currentSpeed.normalized * hitresult.distance * 0.9f;
                transform.position = transform.position + deletmove;
                //同时修正X 
                Vector3 toedit = transform.position;
                float newx = hitresult.point.x + (RectSize.x / 2 + MinFloat);
                toedit.x = newx;
                transform.position = toedit;
                currentSpeed.x = 0.0f;
                Debug.Log("左边是墙");
            }

        }
    }

    bool _enableController = true;
    public void EnableController()
    {
        _enableController = true;
    }

    public void DisableController()
    {
        _enableController = false;
    }

    // Update is called once per frame
    void Update ()
    {
        UpdateSpeed();
        UpdateMove();
        _insky = CheckInSky();
        if(!_insky)
        {
            jumpCount = 0;
        }
        if (_enableController)
        {
            UpdateController();
        }

        Vector3 cp = Camera.main.transform.localPosition;
        cp.x = gameObject.transform.localPosition.x;
        cp.y = gameObject.transform.localPosition.y;
        Camera.main.transform.localPosition = cp;
    }

    float lastupdateTime = -1.0f;
    void DelayUpdateWrap()
    {
        float thistime = Time.time;
        float updateTime = 0.1f;
        if(lastupdateTime == -1.0f)
        {
            lastupdateTime = thistime;
        }
        else
        {
            updateTime = thistime - lastupdateTime;
            lastupdateTime = thistime;
        }

        //每秒触发一次
        //每秒吸入 0.1mol 的氧气 3.2g
        //每秒呼出 0.1mol 的二氧化碳 4.4g
        //先从当前格子中取 , 如果数量不够的话 则去附近的8个格子取 
        //如果某个格子的氧气不够 会去其他格子的氧气 补足
        //如果还不够 则会产生窒息 并对应减少呼出的二氧化碳
        MatterGridBehaviour mgb = MainGame.Instance.GetMatterGridByWorldPosition(transform.position);
        
        if (mgb != null)
        {
            float leftyiyang = mgb.mg.RemoveGasMatter("一氧化碳",0.01f);
            if(leftyiyang != 0.01f)
            {
                ShowDamageco();
                //一氧化碳 中毒了
                Damage((0.01f  - leftyiyang) * 100.0f );
            }
            if(mgb.mg.Temperature < 0.0f)
            {
                ShowDamagecool();
                Damage(updateTime);
            }
            float left = mgb.mg.RemoveGasMatter("氧气", 0.0032f * updateTime);
            if (left > 0.0f)
            {
                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        MatterGridBehaviour mgb1 = MainGame.Instance.GetMatterGridByWorldPosition(transform.position + new Vector3(i, j, 0.0f));
                        if (mgb1 != null)
                        {
                            left = mgb1.mg.RemoveGasMatter("氧气", left);
                            if (left == 0.0f)
                            {
                                goto L1;
                            }
                        }
                    }
                }
            }
        L1: float masseryanghuatan = (0.0032f * updateTime - left) * 4.4f / 3.2f;
            if(masseryanghuatan > 0)
            {
                mgb.mg.AddMatter(new Matter() { currentMatterState = Matter.MatterState.Gas, Mass = masseryanghuatan, matterType = MatterTypeConfig.AllMatters["二氧化碳"], Temperature = 37.0f });
            }
            if (left > 0.0f)
            {
                ShowDamageo2();
                //todo 憋气
                Damage(10.0f * updateTime);
            }
            //每秒会释放 1KJ 的热量
            mgb.mg.EnergyChange(1.0f * updateTime);
        }
    }
    IEnumerator DelayUpdate()  //每秒更新一次
    {
        while(true)
        {
            yield return new WaitForSeconds(0.1f);
            DelayUpdateWrap();
        }

    }


    void OnCollisionStay2D(Collision2D collisionInfo)
    {
//        Debug.Log("OnCollisionStay");
    }

    void OnCollisionEnter2D(Collision2D collisionInfo)
    {
        if(collisionInfo.relativeVelocity.x < 0.0f)
        {
            Debug.Log("CollisionRightWall");
        }
        if (collisionInfo.relativeVelocity.x > 0.0f)
        {
            Debug.Log("CollisionLeftWall");
        }
        Debug.Log(collisionInfo.gameObject.name);
        Debug.Log(collisionInfo.relativeVelocity);
    }

    RaycastHit2D[] downhitTest = new RaycastHit2D[10];


    bool CheckInSky()
    {
        if (currentSpeed.y > 0.0f)
        {
            return true;
        }
        RaycastHit2D hitresult = Physics2D.BoxCast(transform.position, RectSize, 0, Vector2.down, 0.01f,sceneLayer);
        if(hitresult.collider == null)
        {
            return true;
        }
        return false;
    }




    public void MakeGouHuo()
    {
        if (_insky)
        {
            return;
        }
        if(transform.position.y > 5.0f)
        {
//            MainGame.Instance.ShowChengGuanTip();
            return;
        }

        GameObject go = GameObject.Instantiate(GouHuo) as GameObject;
        go.transform.localPosition = transform.position;
        GouHuo gouhuo = go.GetComponent<GouHuo>();
        int x = (int)transform.position.x;
        int y = (int)transform.position.y;
        gouhuo.SetPosition(x, y);
    }

    float maxHP = 1000.0f;
    float _currentHP = 1000.0f;

    public GameObject hpdamage;
    
    public void Damage(float hp)
    {
        hp = hp * 10.0f;               
        _currentHP -= hp;
        _currentHP = Mathf.Max(0.0f, _currentHP);
        if(_currentHP <=     0.0f)
        {
            MainGame.Instance.GameOver();
        }
        Vector3 size = hpdamage.transform.localScale;
        size.x = _currentHP / maxHP * 50.0f;
        hpdamage.transform.localScale = size;
        Vector3 p = hpdamage.transform.localPosition;
        p.x = -(50.0f - size.x) / 16.0f;
        hpdamage.transform.localPosition = p;
    }
    Coroutine o2;
    Coroutine co;
    Coroutine cool;


    public void ShowDamageo2()
    {
        if(o2 !=null)
        {
            StopCoroutine(o2);
        }
        o2 = StartCoroutine(sdo2());
    }

    IEnumerator sdo2()
    {
        noO2damage.SetActive(true);
        yield return new WaitForSeconds(0.8f);
        noO2damage.SetActive(false);
    }



    public void ShowDamageco()
    {
        if (co != null)
        {
            StopCoroutine(co);
        }
        co = StartCoroutine(sdco());
    }

    IEnumerator sdco()
    {
        yiyanghuatanDamage.SetActive(true);
        yield return new WaitForSeconds(0.8f);
        yiyanghuatanDamage.SetActive(false);
    }


    public void ShowDamagecool()
    {
        if (cool != null)
        {
            StopCoroutine(cool);
        }
        cooldamage.SetActive(true);
        cool = StartCoroutine(sdcool());
    }

    IEnumerator sdcool()
    {
        yield return new WaitForSeconds(0.8f);
        cooldamage.SetActive(false);
    }

}
